package cn.edu.fzu.homemaking.sso.session;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.edu.fzu.homemaking.web.Result;
import cn.edu.fzu.homemaking.web.RetCode;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import static cn.edu.fzu.homemaking.common.SessionConstant.*;

@Order(0)
@WebFilter(urlPatterns = "/api/sso/*")
@Component
public class RedisSessionFilter implements Filter {

    private static final Logger log = LoggerFactory.getLogger(RedisSessionFilter.class);

    private final SessionCache  sessionCache;

    @Autowired
    RedisSessionFilter(@Qualifier("sessionCache") SessionCache sessionCache) {
        this.sessionCache = sessionCache;
    }


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // do nothing
    }


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse rsp = (HttpServletResponse) response;

        boolean logout = LOGOUT_URI.equals(req.getRequestURI());

        String domain = req.getServerName();

        // 将 session id 写入 cookie, 如果是退出登录, 则删除 cookie
        Cookie cookie = getOrCreateSessionCookie(req);
        cookie.setDomain(domain);
        cookie.setPath(COOKIE_PATH);
        cookie.setMaxAge(logout ? 0 : SESSION_TIMEOUT);
        rsp.addCookie(cookie);

        String dSessionId = cookie.getValue();
        RedisSession session = sessionCache.get(dSessionId);
        if (logout) {
            sessionCache.invalidate(dSessionId);
        }
        if (!session.isNew()) {
            rsp.getWriter().print(JSON
                    .toJSONString(new Result(RetCode.REFUSE_LOGIN, null, "账号异地登录，请退出登录后，重新登录，为了确保账号安全，建议修改密码！", null)));
            return;
        }

        try (RedisSessionRequest requestWrapper = new RedisSessionRequest(req, session)) {
            chain.doFilter(requestWrapper, response);
        }

    }


    @Override
    public void destroy() {
        // do nothing
    }


    // 从 web 端请求中获取 cookie, 如果没有就创建一个
    private static Cookie getOrCreateSessionCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        log.error("sessionId:" + request.getSession().getId());
        if (ArrayUtils.isNotEmpty(cookies)) {
            for (Cookie item : cookies) {
                log.error("cookie item:" + item);
                if (DSESSIONID.equals(item.getName())) {
                    return item;
                }
            }
        }
        return new Cookie(DSESSIONID, request.getSession().getId());
    }

}
